<form name="form" ng-init="vm.init();refresh(vm.callback);" ng-submit="vm.mapping(form.$valid)" novalidate>
  <div class="row x-page-header">
    <div class="col-md-12">
      <div class="x-page-title">MyBatis 映射文件</div>
      <div class="pull-right">
        <button class="btn btn-primary" type="submit" ng-disabled="form.$invalid || !vm.hasSql">映射</button>
        <div class="btn-group x-btn-list">
          <button id="copy" class="btn btn-success" type="button" data-clipboard-action="copy"
              ng-disabled="!vm.hasCode">复制</button>
          <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown"
              ng-disabled="!vm.hasCode">
            <span class="caret"></span>
          </button>
          <ul class="dropdown-menu dropdown-menu-right">
            <li><button type="button" class="btn btn-default btn-block" ng-click="vm.save()">保存文件</button></li>
          </ul>
        </div>
        <button class="btn btn-danger" type="button" ng-click="vm.reset()">重置</button>
      </div>
    </div>
  </div>
  <div class="row x-page-body">
    <div class="col-md-6">
      <fieldset>
        <legend>映射表与模板</legend>
        <div class="x-page-scope">
          <div class="form-group">
            <div class="input-group">
              <input type="text" name="daoName" class="form-control" ng-model="vm.daoName" autofocus required
                  placeholder="DAO全名（package.class）" ng-class="{'x-invalid': form.$submitted && form.daoName.$invalid}">
              <span class="input-group-addon">.java</span>
            </div>
          </div>
          <div class="form-group">
            <div class="input-group">
              <input type="text" name="modelName" class="form-control" ng-model="vm.modelName" required
                  placeholder="Model全名（package.class）" ng-class="{'x-invalid': form.$submitted && form.modelName.$invalid}">
              <span class="input-group-addon">.java</span>
            </div>
          </div>
          <div class="form-group">
            <div class="input-group">
              <input type="text" name="mapperName" class="form-control" ng-model="vm.mapperName" required
                  placeholder="Mapper文件名" ng-class="{'x-invalid': form.$submitted && form.mapperName.$invalid}">
              <span class="input-group-addon">.xml</span>
            </div>
          </div>
          <div class="form-group">
            <label class="control-label">SQL与模板
              <font color="green" style="font-weight:normal">（类型标识符：{jdbcType:VARCHAR,javaType:String}）</font>
            </label>
            <uib-tabset active="0" type="tabs" class="x-mapper">
              <uib-tab index="0" heading="SQL">
                <div class="x-editor">
                  <pre id="sql-editor"></pre>
                </div>
              </uib-tab>
              <uib-tab index="1" heading="DAO">
                <textarea name="daoTemplate" class="form-control" ng-model="vm.templates.dao" required
                    ng-class="{'x-invalid': form.$submitted && form.daoTemplate.$invalid}"></textarea>
              </uib-tab>
              <uib-tab index="2" heading="Model">
                <textarea name="modelTemplate" class="form-control" ng-model="vm.templates.model" required
                    ng-class="{'x-invalid': form.$submitted && form.modelTemplate.$invalid}"></textarea>
              </uib-tab>
              <uib-tab index="3" heading="Mapper">
                <textarea name="mapperTemplate" class="form-control" ng-model="vm.templates.mapper" required
                    ng-class="{'x-invalid': form.$submitted && form.mapperTemplate.$invalid}"></textarea>
              </uib-tab>
            </uib-tabset>
          </div>
        </div>
      </fieldset>
    </div>
    <div class="col-md-6">
      <fieldset>
        <legend>映射文件</legend>
        <div class="x-page-scope">
          <div ng-show="vm.error == ''">
            <uib-tabset active="vm.activeTab" type="tabs" class="x-mapper">
              <uib-tab index="0" heading="DAO">
                <pre class="x-output" id="dao-viewer"></pre>
              </uib-tab>
              <uib-tab index="1" heading="Model">
                <pre class="x-output" id="model-viewer"></pre>
              </uib-tab>
              <uib-tab index="2" heading="Mapper">
                <pre class="x-output" id="mapper-viewer"></pre>
              </uib-tab>
            </uib-tabset>
          </div>
          <pre class="alert alert-danger" ng-if="vm.error">{{vm.error}}</pre>
        </div>
      </fieldset>
    </div>
  </div>
<script type="text/template" id="dao-template">
<%
var primaryKeys = _.filter(table.columns, function(column) {
    return column.primaryKey;
});
%>
<%if (dao.packageName) {%>
package <%=dao.packageName%>;
<%}%>
import <%=model.name%>;

public interface <%=dao.className%> {

    <%=model.className%> select(<%=_.map(primaryKeys, function(column) {
        return column.javaType + ' ' + column.javaName;
    }).join(', ')%>);

    List<<%=model.className%>> selectList(<%=model.className%> model);

    List<<%=model.className%>> selectAll();

    long selectCount(<%=model.className%> model);

    int insert(<%=model.className%> model);

    int update(<%=model.className%> model);

    int delete(<%=_.map(primaryKeys, function(column) {
        return column.javaType + ' ' + column.javaName;
    }).join(', ')%>);

    int deleteList(<%=model.className%> model);

    int deleteAll();

}
</script>
<script type="text/template" id="model-template">
<%
var toUpperCase = function(name) {
    return name.substring(0,1).toUpperCase() + name.substring(1);
}
%>
<%if (model.packageName) {%>
package <%=model.packageName%>;
<%}%>
import java.io.Serializable;

public class <%=model.className%> implements Serializable {
<%_.each(_.union(table.primaryKeys, table.columns), function(column) {%>
    private <%=column.javaType%> <%=column.javaName%>;
<%})%><%_.each(_.union(table.primaryKeys, table.columns), function(column) {%>
    public <%=column.javaType%> get<%=toUpperCase(column.javaName)%>() {
        return <%=column.javaName%>;
    }

    public void set<%=toUpperCase(column.javaName)%>(<%=column.javaType%> <%=column.javaName%>) {
        this.<%=column.javaName%> = <%=column.javaName%>;
    }
<%})%>
}
</script>
<script type="text/template" id="mapper-template">
<%
var primaryKeys = _.filter(table.columns, function(column) {
    return column.primaryKey;
});
var line = 0, columnLines = [''];
_.each(table.columns, function(column, i) {
    columnLines[line] += column.name;
    if (i < table.columns.length - 1) {
        columnLines[line] += ',';
        if (columnLines[line].length < 100) {
            columnLines[line] += ' ';
        } else {
            line++;
            columnLines.push('');
        }
    }
});
%>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="<%=dao.name%>">
  <select id="select" resultType="<%=model.name%>">
    SELECT <%=columnLines.join('\n      ')%>
    FROM <%=table.name%>
    WHERE <%=_.map(primaryKeys, function(column, i) {
        return column.name + ' = #{' + i + ',jdbcType=' + column.jdbcType + '}';
    }).join(' AND ')%>
  </select>
  <select id="selectList" resultType="<%=model.name%>">
    SELECT <%=columnLines.join('\n      ')%>
    FROM <%=table.name%>
    <where><%_.each(table.columns, function(column) {%>
      <if test="<%=column.javaName%> != null">
        AND <%=column.name%> = #{<%=column.javaName%>,jdbcType=<%=column.jdbcType%>}
      </if><%})%>
    </where>
  </select>
  <select id="selectAll" resultType="<%=model.name%>">
    SELECT <%=columnLines.join('\n      ')%>
    FROM <%=table.name%>
  </select>
  <select id="selectCount" resultType="long">
    SELECT COUNT(1) FROM <%=table.name%>
    <where><%_.each(table.columns, function(column) {%>
      <if test="<%=column.javaName%> != null">
        AND <%=column.name%> = #{<%=column.javaName%>,jdbcType=<%=column.jdbcType%>}
      </if><%})%>
    </where>
  </select>
  <insert id="insert" useGeneratedKeys="true" keyProperty="<%=_.map(primaryKeys, function(column) {
        return column.name;
    }).join(',')%>">
    INSERT INTO <%=table.name%>
    <trim prefix="(" suffix=")" suffixOverrides=","><%_.each(_.difference(table.columns, primaryKeys),
      function(column) {%>
      <if test="<%=column.javaName%> != null">
        <%=column.name%>,
      </if><%})%>
    </trim>
    <trim prefix="VALUES (" suffix=")" suffixOverrides=","><%_.each(_.difference(table.columns, primaryKeys),
      function(column) {%>
      <if test="<%=column.javaName%> != null">
        #{<%=column.javaName%>,jdbcType=<%=column.jdbcType%>},
      </if><%})%>
    </trim>
  </insert>
  <update id="update">
    UPDATE <%=table.name%>
    <set><%_.each(_.difference(table.columns, primaryKeys), function(column) {%>
      <if test="<%=column.javaName%> != null">
        <%=column.name%> = #{<%=column.javaName%>,jdbcType=<%=column.jdbcType%>},
      </if><%})%>
    </set>
    WHERE <%=_.map(primaryKeys, function(column) {
        return column.name + ' = #{' + column.javaName + ',jdbcType=' + column.jdbcType + '}';
    }).join(' AND ')%>
  </update>
  <delete id="delete">
    DELETE FROM <%=table.name%>
    WHERE <%=_.map(primaryKeys, function(column, i) {
        return column.name + ' = #{' + i + ',jdbcType=' + column.jdbcType + '}';
    }).join(' AND ')%>
  </delete>
  <delete id="deleteList">
    DELETE FROM <%=table.name%>
    <where><%_.each(table.columns, function(column) {%>
      <if test="<%=column.javaName%> != null">
        AND <%=column.name%> = #{<%=column.javaName%>,jdbcType=<%=column.jdbcType%>}
      </if><%})%>
    </where>
  </delete>
  <delete id="deleteAll">
    DELETE FROM <%=table.name%>
  </delete>
</mapper>
</script>
</form>
